package com.lzb.video.utils;

import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceHolder;


import java.io.IOException;
import java.util.List;

/**
 * 摄像头帮助工具类 {@link android.hardware.Camera}
 * <h3>Description</h3>
 * TODO
 * <h3>Author</h3> Eric
 * <h3>Date</h3> 2017/10/14 15:57
 * <h3>Copyright</h3> Copyright (c)2017 Shenzhen TLKY  Co., Ltd. Inc. All rights reserved.
 */
public class CameraHelpUtil {

    private static final String TAG = CameraHelpUtil.class.getName();
    public static  boolean  DEBUG = true;
    /** 视频尺寸比率 */
    public static final float VIDEO_SIZE_RATE = 2.0f;
    /** 视频流码率 */
    public static final int VIDEO_BIT_RATE = 256000 * 3;
    /**
     * 打开摄像头
     * @param cameraId 需要打开的摄像头ID
     * @return
     */
    public static Camera open(int cameraId) {
        //获取摄像头数目
        int numCameras = Camera.getNumberOfCameras();
        if (numCameras == 0) {
            Log.w(TAG, "No cameras!");
            return null;
        }
        // cameraId the hardware camera to access, between 0 and numCameras(摄像头数目) - 1
        boolean explicitRequest = cameraId >= 0;

        if (!explicitRequest) {
            // Select a camera if no explicit camera requested
            int index = 0;
            while (index < numCameras) {
                Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
                Camera.getCameraInfo(index, cameraInfo);
                //判断使用是前置还是后置摄像头 如果是后置摄像头则停止循环
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                    break;
                }
                index++;
            }

            cameraId = index;
        }

        Camera camera;
        if (cameraId < numCameras) {
            printMessage("Opening camera #" + cameraId);
            camera = Camera.open(cameraId);
        } else {
            if (explicitRequest) {
                Log.w(TAG, "Requested camera does not exist: " + cameraId);
                camera = null;
            } else {// cameraId 值 小于 0 且 不存在后置摄像头时，会走这里
                printMessage( "No camera facing back; returning camera #0");
                camera = Camera.open(0);
            }
        }

        return camera;
    }

    /**
     * Opens a rear-facing camera with {@link Camera#open(int)}, if one exists,
     * or opens camera 0.
     *
     * @return handle to {@link Camera} that was opened
     */
    public static Camera open() {
        return open(-1);
    }


    /**
     * 设置摄像头参数，录制视频时使用该方法
     * @param camera 摄像头
     * @param profile 该参数为摄像机配置文件，里面保存类摄像机的参数
     * @param whiteBalance  白平衡   可以为 null
     * @param colorEffect 颜色效果   可以为 null
     * @return 摄像头参数类 {@link Camera.Parameters } 对象
     */
    public static Camera.Parameters setCameraParameters(Camera camera , CamcorderProfile profile , String whiteBalance , String colorEffect){
        if (camera == null){
            printMessage("camera can not null !");
            return null;
        }
        if (profile == null){
            printMessage("profile can not null !");
            return null;
        }


        //因为android不支持竖屏录制，所以需要顺时针转90度，让其游览器显示正常
        camera.setDisplayOrientation(90);

        Camera.Parameters parameters = camera.getParameters();
        //设置预览图片的大小
        parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
        //设置预览图片的帧率
        parameters.setPreviewFrameRate(profile.videoFrameRate);
        //设置获焦模式
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

        if (TextUtils.isEmpty(whiteBalance)){
            whiteBalance = "auto";
        }
        if (TextUtils.isEmpty(colorEffect)){
            colorEffect = "none";
        }
        // 设置白平衡参数。
        if (isSupported(whiteBalance, parameters.getSupportedWhiteBalance())) {
            parameters.setWhiteBalance(whiteBalance);
        }
        // 参数设置颜色效果。
        if (isSupported(colorEffect, parameters.getSupportedColorEffects())) {
            parameters.setColorEffect(colorEffect);
        }

        camera.setParameters(parameters);
        return parameters;
    }

    /**
     *
     * @param isHigh true 高视频质量 否则低视频质量
     * @return 摄像机配置文件 {@link CamcorderProfile}
     */
    public static CamcorderProfile setCamcorderProfile(boolean isHigh ){
        //返回后置相机的配置信息的类
        CamcorderProfile  profile  = CamcorderProfile.get(isHigh ? CamcorderProfile.QUALITY_HIGH : CamcorderProfile.QUALITY_LOW);
        //设置视频帧的宽度
        profile.videoFrameWidth = (int) (profile.videoFrameWidth * VIDEO_SIZE_RATE);
        //设置视频帧的高度
        profile.videoFrameHeight = (int) (profile.videoFrameHeight * VIDEO_SIZE_RATE);
        //设置视频输出比特率 The target video output bit rate in bits per second
        profile.videoBitRate =  VIDEO_BIT_RATE;
        CamcorderProfile highProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
        //The video encoder being used for the video track 设置视频编码
        profile.videoCodec = highProfile.videoCodec;
        //设置音频编码
        profile.audioCodec = highProfile.audioCodec;
        //The file output format of the camcorder profile 设置输出格式
        profile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
        return profile;
    }

    /**
     * 开始预览
     * @param camera
     * @param holder
     */
    public static void startPreview(Camera camera,SurfaceHolder holder) {
        try {
            if (camera != null) {
                camera.setPreviewDisplay(holder);
                camera.startPreview();
            }
        } catch (IOException e) {
            printMessage(e.getMessage());
        }
    }

    public static void releaseCamera(Camera camera) {
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.stopPreview();// 停掉原来摄像头的预览
            camera.release();
            camera = null;
        }
    }


    private static boolean isSupported(String value, List<String> supported) {
        return supported == null ? false : supported.indexOf(value) >= 0;
    }

    private static void printMessage(String msg){
        if (DEBUG){
            Log.i(TAG,msg);
        }
    }

}
